package cz.cuni.mff.ufal.volk;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.log4j.Logger;

import cz.cuni.mff.ufal.volk.command.Command;
import cz.cuni.mff.ufal.volk.events.NabaztagEventListener;

/**
 * The class represents a Nabaztag connected to the server.
 *
 * @author Bartłomiej Etenkowski
 */
public class NabaztagImpl {

	private static final Logger log = Logger.getLogger(NabaztagImpl.class);

  /**
   * Creates a Nabaztag with the given serial number.
   *
   * @param serial
   */
  public NabaztagImpl(String serial) {
    if (serial == null)
      throw new NullPointerException("The serial argument is null");

    this.serial = serial;
    this.created = new Date();
  }

  private final String serial;

  /** @return the serial number of this Nabaztag */
  public String getSerial() {
    return serial;
  }

  private Date created;

  public Date getCreated() {
    return created;
  }

  final List<NabaztagEventListener> eventListeners = new ArrayList<NabaztagEventListener>();

  public boolean addEventListener(NabaztagEventListener listener) {
    listener.getClass(); // to ensure that the listener is not null
    synchronized (eventListeners) {
      if (eventListeners.contains(listener))
        return false; // no listener can be added twice
      else
        return eventListeners.add(listener);
    }
  }

  public boolean removeEventListener(NabaztagEventListener listener) {
    synchronized (eventListeners) {
      return eventListeners.remove(listener);
    }
  }

  private final Queue<Command> commandQueue = new ConcurrentLinkedQueue<Command>();

  public boolean enqueueCommand(Command command) {
  	log.trace("enqueuing command: " + command.id);
    return commandQueue.add(command);
  }

  public Command dequeueCommand() {
  	Command command = commandQueue.poll();
  	if (command != null)
  		log.trace("dequeuing command: " + command.id);
    return command;
  }
}
